<template>
  <div class="mindmap-window">
    <!-- 窗口标题栏和工具栏 -->
    <div class="window-header">
      <div class="header-left">
        <div class="window-title">思维导图</div>
        <div class="toolbar-divider"></div>
        <MindMapToolbar
          :selected-node="!!selectedNode"
          @add="handleAddNode"
          @delete="handleDeleteNode"
          @zoom-in="handleZoomIn"
          @zoom-out="handleZoomOut"
          @zoom-fit="handleZoomFit"
          @import="handleImport"
          @export="handleExport"
          @export-markdown="handleExportMarkdown"
        />
      </div>
      <button class="window-close" @click="handleClose">
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
          <path d="M12.72 3.293a1 1 0 0 0-1.415 0L8 6.586 4.697 3.293a1 1 0 1 0-1.414 1.414L6.586 8l-3.303 3.293a1 1 0 0 0 1.414 1.414L8 9.414l3.303 3.293a1 1 0 0 0 1.414-1.414L9.414 8l3.303-3.293a1 1 0 0 0 0-1.414z"/>
        </svg>
      </button>
    </div>
    
    <!-- 思维导图容器 -->
    <div id="container" ref="container" class="mindmap-container"></div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
import { Graph, Cell, Node, Path } from '@antv/x6'
import { Selection } from '@antv/x6-plugin-selection'
import { Keyboard } from '@antv/x6-plugin-keyboard'
import { Transform } from '@antv/x6-plugin-transform'
import Hierarchy from '@antv/hierarchy'
import insertCss from 'insert-css'
import MindMapToolbar from '../components/chat/MindMapToolbar.vue'
import { ElMessage } from 'element-plus'
import { parseMermaidToTree, convertToMindMapData } from '../utils/mermaidParser'

// 定义emit
const emit = defineEmits<{
  (e: 'close'): void
  (e: 'export-markdown'): void
}>()

// 处理关闭按钮点击
const handleClose = () => {
  emit('close')
}

// 选中节点状态
const selectedNode = ref<Node | null>(null)

// 缩放相关
const ZOOM_STEP = 0.1
const MIN_ZOOM = 0.2
const MAX_ZOOM = 2.0

// 记录当前缩放值的状态变量
const currentZoom = ref(1.0)

// 工具栏事件处理
const handleAddNode = () => {
  if (selectedNode.value) {
    const type = selectedNode.value.prop('type')
    if (addChildNode(selectedNode.value.id, type)) {
      render()
    }
  }
}

const handleDeleteNode = () => {
  if (selectedNode.value) {
    if (removeNode(selectedNode.value.id)) {
      render()
      selectedNode.value = null
    }
  }
}

// 修正缩放处理函数
const handleZoomIn = () => {
  if (!graph.value) return
  
  // 获取当前缩放值
  const zoom = graph.value.zoom()
  console.log(`Before zoom in: ${zoom}`)
  
  if (zoom < MAX_ZOOM) {
    // 使用X6的zoomTo方法设置新的缩放值
    const newZoom = Math.min(zoom + ZOOM_STEP, MAX_ZOOM)
    graph.value.zoomTo(newZoom)
    
    // 更新当前缩放状态
    currentZoom.value = newZoom
    console.log(`After zoom in: ${newZoom}`)
  }
}

const handleZoomOut = () => {
  if (!graph.value) return
  
  // 获取当前缩放值
  const zoom = graph.value.zoom()
  console.log(`Before zoom out: ${zoom}`)
  
  if (zoom > MIN_ZOOM) {
    // 使用X6的zoomTo方法设置新的缩放值
    const newZoom = Math.max(zoom - ZOOM_STEP, MIN_ZOOM)
    graph.value.zoomTo(newZoom)
    
    // 更新当前缩放状态
    currentZoom.value = newZoom
    console.log(`After zoom out: ${newZoom}`)
  }
}

const handleZoomFit = () => {
  graph.value?.zoomToFit({ padding: 20 })
  // 更新当前缩放状态
  if (graph.value) {
    currentZoom.value = graph.value.zoom()
  }
}

const handleImport = (data: MindMapData) => {
  try {
    mindMapData.value = data
    render()
    ElMessage.success('导入成功')
  } catch (error) {
    ElMessage.error('导入失败：数据格式错误')
  }
}

const handleExport = () => {
  const data = JSON.stringify(mindMapData.value, null, 2)
  const blob = new Blob([data], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = 'mindmap.json'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
  URL.revokeObjectURL(url)
  ElMessage.success('导出成功')
}

const handleExportMarkdown = () => {
  const convertToMarkdown = (node: MindMapData, level = 0): string => {
    let markdown = `${'  '.repeat(level)}- ${node.label}\n`
    if (node.children) {
      node.children.forEach(child => {
        markdown += convertToMarkdown(child, level + 1)
      })
    }
    return markdown
  }

  const markdownContent = convertToMarkdown(mindMapData.value)
  const blob = new Blob([markdownContent], { type: 'text/markdown' })
  const url = URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = 'mindmap.md'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
  URL.revokeObjectURL(url)
  ElMessage.success('导出Markdown成功')
}

// 注册节点、连接器和边的类型
const registerGraphComponents = () => {
  // 中心主题或分支主题
  Graph.registerNode(
    'topic',
    {
      inherit: 'rect',
      markup: [
        {
          tagName: 'rect',
          selector: 'body',
        },
        {
          tagName: 'image',
          selector: 'img',
        },
        {
          tagName: 'text',
          selector: 'label',
        },
      ],
      attrs: {
        body: {
          rx: 6,
          ry: 6,
          stroke: '#5F95FF',
          fill: '#EFF4FF',
          strokeWidth: 1,
        },
        img: {
          ref: 'body',
          refX: '100%',
          refY: '50%',
          refY2: -8,
          width: 16,
          height: 16,
          'xlink:href':
            'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*SYCuQ6HHs5cAAAAAAAAAAAAAARQnAQ',
          event: 'add:topic',
          class: 'topic-image',
        },
        label: {
          fontSize: 14,
          fill: '#262626',
        },
      },
      tools: [{
        name: 'node-editor',
        args: {
          attrs: {
            backgroundColor: '#FFFFFF',
            border: '1px solid #5F95FF',
            padding: '4px 8px',
            borderRadius: 4,
          },
          autoFocus: true,
        },
      }],
    },
    true,
  )

  // 子主题
  Graph.registerNode(
    'topic-child',
    {
      inherit: 'rect',
      markup: [
        {
          tagName: 'rect',
          selector: 'body',
        },
        {
          tagName: 'text',
          selector: 'label',
        },
        {
          tagName: 'path',
          selector: 'line',
        },
      ],
      attrs: {
        body: {
          fill: '#ffffff',
          strokeWidth: 0,
          stroke: '#5F95FF',
        },
        label: {
          fontSize: 14,
          fill: '#262626',
          textVerticalAnchor: 'bottom',
        },
        line: {
          stroke: '#5F95FF',
          strokeWidth: 2,
          d: 'M 0 15 L 60 15',
        },
      },
      tools: [{
        name: 'node-editor',
        args: {
          attrs: {
            backgroundColor: '#FFFFFF',
            border: '1px solid #5F95FF',
            padding: '4px 8px',
            borderRadius: 4,
          },
          autoFocus: true,
        },
      }],
    },
    true,
  )

  // 连接器
  Graph.registerConnector(
    'mindmap',
    (sourcePoint, targetPoint, _unused, options) => {
      const midX = sourcePoint.x + 10
      const midY = sourcePoint.y
      const ctrX = (targetPoint.x - midX) / 5 + midX
      const ctrY = targetPoint.y
      const pathData = `
       M ${sourcePoint.x} ${sourcePoint.y}
       L ${midX} ${midY}
       Q ${ctrX} ${ctrY} ${targetPoint.x} ${targetPoint.y}
      `
      return options.raw ? Path.parse(pathData) : pathData
    },
    true,
  )

  // 边
  Graph.registerEdge(
    'mindmap-edge',
    {
      inherit: 'edge',
      connector: {
        name: 'mindmap',
      },
      attrs: {
        line: {
          targetMarker: '',
          stroke: '#A2B1C3',
          strokeWidth: 2,
        },
      },
      zIndex: 0,
    },
    true,
  )
}

// 类型定义
interface MindMapData {
  id: string
  type: 'topic' | 'topic-branch' | 'topic-child'
  label: string
  width: number
  height: number
  children?: MindMapData[]
}

interface HierarchyResult {
  id: string
  x: number
  y: number
  data: MindMapData
  children?: HierarchyResult[]
}

// 组件状态
const container = ref<HTMLElement | null>(null)
const graph = ref<Graph | null>(null)
const mindMapData = ref<MindMapData>({
  id: '1',
  type: 'topic',
  label: '加载中...',
  width: 160,
  height: 50,
  children: []
})

// 添加props接收mermaid代码
const props = defineProps<{
  mermaidCode?: string
}>()

// 监听mermaid代码变化
watch(() => props.mermaidCode, (newCode) => {
  if (newCode) {
    try {
      console.log('Parsing mermaid code:', newCode)
      const parsedTree = parseMermaidToTree(newCode)
      const convertedData = convertToMindMapData(parsedTree)
      console.log('Parsed mind map data:', convertedData)
      
      mindMapData.value = convertedData
      nextTick(() => {
        render()
        // 在渲染完成后自动适应画布
        handleZoomFit()
      })
    } catch (error) {
      console.error('Error parsing mermaid code:', error)
      mindMapData.value = {
        id: 'error',
        type: 'topic',
        label: '解析错误',
        width: 160,
        height: 50,
        children: [{
          id: 'error-detail',
          type: 'topic-child',
          label: error instanceof Error ? error.message : '无效的mermaid代码',
          width: 200,
          height: 30
        }]
      }
      render()
      // 在错误状态下也自动适应画布
      nextTick(() => {
        handleZoomFit()
      })
    }
  }
}, { immediate: true })

const isPanningMode = ref(false) // 是否处于空格键拖拽模式

// 查找节点
const findItem = (
  obj: MindMapData,
  id: string,
): {
  parent: MindMapData | null
  node: MindMapData | null
} | null => {
  if (obj.id === id) {
    return {
      parent: null,
      node: obj,
    }
  }
  const { children } = obj
  if (children) {
    for (let i = 0, len = children.length; i < len; i += 1) {
      const res = findItem(children[i], id)
      if (res) {
        return {
          parent: res.parent || obj,
          node: res.node,
        }
      }
    }
  }
  return null
}

// 添加子节点
const addChildNode = (id: string, type: string) => {
  const res = findItem(mindMapData.value, id)
  const dataItem = res?.node
  if (dataItem) {
    let item: MindMapData | null = null
    const length = dataItem.children ? dataItem.children.length : 0
    if (type === 'topic') {
      item = {
        id: `${id}-${length + 1}`,
        type: 'topic-branch',
        label: `分支主题${length + 1}`,
        width: 100,
        height: 40,
      }
    } else if (type === 'topic-branch') {
      item = {
        id: `${id}-${length + 1}`,
        type: 'topic-child',
        label: `子主题${length + 1}`,
        width: 60,
        height: 30,
      }
    }
    if (item) {
      if (dataItem.children) {
        dataItem.children.push(item)
      } else {
        dataItem.children = [item]
      }
      return item
    }
  }
  return null
}

// 删除节点
const removeNode = (id: string) => {
  const res = findItem(mindMapData.value, id)
  const dataItem = res?.parent
  if (dataItem && dataItem.children) {
    const { children } = dataItem
    const index = children.findIndex((item) => item.id === id)
    return children.splice(index, 1)
  }
  return null
}

// 渲染思维导图
const render = () => {
  if (!graph.value) return

  const result: HierarchyResult = Hierarchy.mindmap(mindMapData.value, {
    direction: 'H',
    getHeight(d: MindMapData) {
      return d.height
    },
    getWidth(d: MindMapData) {
      return d.width
    },
    getHGap() {
      return 40
    },
    getVGap() {
      return 20
    },
    getSide: () => {
      return 'right'
    },
  })

  const cells: Cell[] = []
  const traverse = (hierarchyItem: HierarchyResult) => {
    if (hierarchyItem) {
      const { data, children } = hierarchyItem
      cells.push(
        graph.value!.createNode({
          id: data.id,
          shape: data.type === 'topic-child' ? 'topic-child' : 'topic',
          x: hierarchyItem.x,
          y: hierarchyItem.y,
          width: data.width,
          height: data.height,
          label: data.label,
          type: data.type,
        }),
      )
      if (children) {
        children.forEach((item: HierarchyResult) => {
          const { id, data } = item
          cells.push(
            graph.value!.createEdge({
              shape: 'mindmap-edge',
              source: {
                cell: hierarchyItem.id,
                anchor:
                  data.type === 'topic-child'
                    ? {
                        name: 'right',
                        args: {
                          dx: -16,
                        },
                      }
                    : {
                        name: 'center',
                        args: {
                          dx: '25%',
                        },
                      },
              },
              target: {
                cell: id,
                anchor: {
                  name: 'left',
                },
              },
            }),
          )
          traverse(item)
        })
      }
    }
  }
  traverse(result)
  graph.value.resetCells(cells)
  graph.value.centerContent()
}

// 组件生命周期
// 键盘事件处理函数
const handleKeyDown = (e: KeyboardEvent) => {
  if (e.code === 'Space') {
    e.preventDefault() // 防止页面滚动
    isPanningMode.value = true
    if (container.value) {
      container.value.style.cursor = 'grab'
    }
  }
}

const handleKeyUp = (e: KeyboardEvent) => {
  if (e.code === 'Space') {
    isPanningMode.value = false
    if (container.value) {
      container.value.style.cursor = 'default'
    }
  }
}

onMounted(() => {
  if (!container.value) return

  registerGraphComponents()

  // 添加键盘事件监听
  window.addEventListener('keydown', handleKeyDown)
  window.addEventListener('keyup', handleKeyUp)

  graph.value = new Graph({
    container: container.value,
    connecting: {
      connectionPoint: 'anchor',
    },
    interacting: {
      nodeMovable: false,
    },
    // 添加缩放配置
    scaling: {
      min: MIN_ZOOM,
      max: MAX_ZOOM,
    },
    // 添加画布拖拽配置
    panning: {
      enabled: true,
      eventTypes: ['leftMouseDown'],
      modifiers: ['space'], // 使用空格键作为修饰键
    },
    mousewheel: {
      enabled: true,
      zoomAtMousePosition: true,
      modifiers: ['ctrl'],
      minScale: MIN_ZOOM,
      maxScale: MAX_ZOOM,
      factor: 1.1, // 平滑的缩放因子
      global: true, // 允许在整个画布上滚动
    },
  })
  graph.value.zoom(currentZoom.value)
  graph.value.use(new Selection())
  graph.value.use(new Keyboard())
  graph.value.use(new Transform({
    resizing: false,
    rotating: false,
  }))

  // 设置画布拖拽时的鼠标样式
  graph.value.on('blank:mousedown', () => {
    const container = graph.value?.container as HTMLElement
    if (container) {
      container.style.cursor = 'grabbing'
    }
  })

  graph.value.on('blank:mouseup blank:mouseleave', () => {
    const container = graph.value?.container as HTMLElement
    if (container) {
      container.style.cursor = 'default'
    }
  })

  // 默认鼠标样式
  if (container.value) {
    container.value.style.cursor = 'default'
  }

  // 注册事件
  graph.value.on('add:topic', ({ node }: { node: Node }) => {
    const { id } = node
    const type = node.prop('type')
    if (addChildNode(id, type)) {
      render()
    }
  })

  // 选择节点事件
  graph.value.on('cell:selected', ({ cell }) => {
    if (cell.isNode()) {
      selectedNode.value = cell as Node
    }
  })

  graph.value.on('cell:unselected', () => {
    selectedNode.value = null
  })

  graph.value.on('blank:click', () => {
    selectedNode.value = null
    graph.value!.cleanSelection()
  })

  // 快捷键
  graph.value.bindKey(['backspace', 'delete'], () => {
    const selectedNodes = graph.value!.getSelectedCells().filter((item) => item.isNode())
    if (selectedNodes.length) {
      const { id } = selectedNodes[0]
      if (removeNode(id)) {
        render()
      }
    }
  })

  graph.value.bindKey('tab', (e) => {
    e.preventDefault()
    const selectedNodes = graph.value!.getSelectedCells().filter((item) => item.isNode())
    if (selectedNodes.length) {
      const node = selectedNodes[0]
      const type = node.prop('type')
      if (addChildNode(node.id, type)) {
        render()
      }
    }
  })

  // 添加样式
  insertCss(`
    .topic-image {
      visibility: hidden;
      cursor: pointer;
    }
    .x6-node:hover .topic-image {
      visibility: visible;
    }
    .x6-node-selected rect {
      stroke-width: 2px;
    }
  `)

  render()
  // 在初始渲染完成后自动适应画布
  nextTick(() => {
    handleZoomFit()
  })
})

// 监听拖拽模式变化
watch(isPanningMode, (newValue) => {
  if (!graph.value) return
  
  // 更新画布样式和行为
  if (container.value) {
    container.value.style.cursor = newValue ? 'grab' : 'default'
  }
  
  // 在拖拽模式下禁用节点交互
  graph.value.options.interacting = {
    nodeMovable: !newValue,
    edgeMovable: !newValue,
    // 使用正确的属性控制交互
    magnetConnectable: !newValue,
    vertexMovable: !newValue,
    vertexAddable: !newValue,
    vertexDeletable: !newValue,
    arrowheadMovable: !newValue,
  }
})

onBeforeUnmount(() => {
  graph.value?.dispose()
  // 移除键盘事件监听
  window.removeEventListener('keydown', handleKeyDown)
  window.removeEventListener('keyup', handleKeyUp)
})
</script>

<style scoped>
/* 窗口样式 */
.mindmap-window {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

/* 窗口标题栏样式 */
.window-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 16px;
  background-color: #f8fafc;
  border-bottom: 1px solid #e2e8f0;
  cursor: default;
  user-select: none;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 16px;
}

.window-title {
  font-size: 16px;
  font-weight: 500;
  color: #334155;
  white-space: nowrap;
}

.toolbar-divider {
  width: 1px;
  height: 24px;
  background-color: #e2e8f0;
  margin: 0 8px;
}

:deep(.mindmap-toolbar) {
  display: flex;
  gap: 8px;
  align-items: center;
}

:deep(.mindmap-toolbar button) {
  padding: 6px 12px;
  border: 1px solid #e2e8f0;
  background-color: white;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 14px;
  color: #334155;
  display: flex;
  align-items: center;
  gap: 4px;
  height: 32px;
}

:deep(.mindmap-toolbar button:hover) {
  background-color: #f1f5f9;
  border-color: #cbd5e1;
}

:deep(.mindmap-toolbar button:active) {
  background-color: #e2e8f0;
  transform: translateY(1px);
}

.window-close {
  width: 32px;
  height: 32px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: transparent;
  border: none;
  cursor: pointer;
  transition: all 0.2s ease;
}

.window-close:hover {
  background-color: #fee2e2;
}

.window-close:hover svg path {
  fill: #ef4444;
}

.window-close:active {
  transform: scale(0.95);
}

.window-close svg path {
  fill: #64748b;
}

:deep(.mindmap-toolbar) {
  display: flex;
  gap: 8px;
}

:deep(.mindmap-toolbar button) {
  padding: 6px 12px;
  border: 1px solid #e2e8f0;
  background-color: white;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s;
  font-size: 14px;
  color: #334155;
  display: flex;
  align-items: center;
  gap: 4px;
}

:deep(.mindmap-toolbar button:hover) {
  background-color: #f1f5f9;
}

:deep(.mindmap-toolbar button:active) {
  background-color: #e2e8f0;
}

:deep(.mindmap-toolbar button svg) {
  margin-right: 4px;
}

/* 思维导图容器样式 */
.mindmap-container {
  flex: 1;
  background-color: #ffffff;
  position: relative;
  overflow: hidden;
}
</style>